#ifndef HOTEL_H
#define HOTEL_H

#include "reserva.h"
#include "habitacion.h"

class Hotel
{
    public:
        Hotel();
        Hotel(const Nombre n, const Cadena c, const Lista<Habitacion>& hs,
              const Lista<pair<TipoHabitacion, Dinero> > thxd, const Lista<pair<Accesorio, Dinero> > pa);

        Nombre nombre() const;
        Cadena cadena() const;
        Lista<DNI> huespedes() const;
        Lista<Habitacion> habitaciones() const;
        Lista<pair<CheckIn,Habitacion> > ingresos() const;
        Lista<CheckOut> salidas() const;
        Lista<Reserva> reservas() const;
        Dinero tarifaXDia(const TipoHabitacion t) const;
        Dinero precioAccesorio(const Accesorio a) const;

        void vender(const Cadena c);
        void hacerReserva(const Reserva& r);
        bool sobreReservado(const Fecha f) const;
        void registrarHuesped(const DNI d, const Fecha f, const Habitacion& a);
        void desRegistrarHuesped(const DNI d, const Fecha f);
        Lista<DNI> huespedesConPalabra() const;
        Dinero calcularCuenta(const CheckIn i, const CheckOut o, const Habitacion& hb) const;
        bool reservasSolapadas(const DNI d) const;
        bool operator==(const Hotel& ht) const;

        void mostrar(std::ostream& os) const;
		void guardar(std::ostream& os) const;
		void cargar (std::istream& is);

    private:
        Nombre _nombre;
        Cadena _cadena;
        Lista<Habitacion> _habitaciones;
        Lista<pair<TipoHabitacion, Dinero> > _tarifaXDia;
        Lista<pair<Accesorio, Dinero> > _precioAccesorio;
        Lista<pair<CheckIn,Habitacion> > _ingresos;
        Lista<CheckOut> _salidas;
        Lista<Reserva> _reservas;

        enum {ENCABEZADO_ARCHIVO = 'H'};

        template<class T> bool mismos(const Lista<T>& l1, const Lista<T>& l2) const;
        bool salio(pair<CheckIn,Habitacion>& ingreso) const;
        int capacidad() const;
        int plazasReservadas(Fecha f) const;
        int cantidad(const TipoHabitacion tipo) const;
        int cantDias(const CheckIn i, const CheckOut o) const;
        Dinero tarifaXHabitacion(const Habitacion& hb) const;
        Dinero precioXAccesorios (const Habitacion& hb) const;
        bool cumplioReserva(pair<CheckIn,Habitacion>& ingreso) const;
        CheckOut salidaMasProxima(Lista<CheckOut>& salidas) const;
        Lista<Reserva> reservasDe(const DNI d) const;
        bool seSolapan(Reserva r1, Reserva r2) const;
        void mostrarHabitaciones(std::ostream& os) const;
        void mostrarIngresos(std::ostream& os) const;
        void mostrarSalidas(std::ostream& os) const;
        void mostrarReservas(std::ostream& os) const;
        void mostrarTarifas(std::ostream& os) const;
        void mostrarAccesorios(std::ostream& os) const;
		void cargarNombre(std::istream& is);
		void cargarCadena(std::istream& is);
		void cargarHabitaciones(std::istream& is);
		void cargarIngresos(std::istream& is);
		void cargarSalidas(std::istream& is);
		void cargarReservas(std::istream& is);
		void cargarTarifas(std::istream& is);
		void cargarAccesorios(std::istream& is);
		Habitacion habitacionPorNumero(int numero) const;
		TipoHabitacion tipoDeHabitacion(string tipo) const;
		Accesorio getAccesorio(string acc) const;
		Fecha getFechaSalida(DNI dni, Fecha fechaIngreso) const;
};

std::ostream & operator<<(std::ostream & os,const Hotel & h);

#endif // HOTEL_H
